package com.arrogames.rgblabyrinth.game.lighting {
	import com.arrogames.tmx.CoordinateUtil;
	
	import flash.geom.Point;
	
	import ash.core.Engine;
	import ash.core.Node;
	import ash.core.NodeList;
	import ash.core.System;
	
	import net.pixelpracht.tmx.TmxMap;
	
	import starling.extensions.lighting.core.LightLayer;
	import starling.extensions.lighting.lights.DirectionalLight;
	import starling.extensions.lighting.lights.PointLight;
	
	public class LightRenderingSystem extends System {
		private var lightLayer:LightLayer;

		private var pointLightNodes:NodeList;
		private var directionalLightNodes:NodeList;
		
		private var map:TmxMap;
		
		public function LightRenderingSystem(lightLayer:LightLayer, map:TmxMap) {
			super();
			this.lightLayer = lightLayer;
			this.map = map;
		}
		
		override public function addToEngine(engine:Engine):void {
			super.addToEngine(engine);
			
			pointLightNodes = register(engine, PointLightNode, pointLightNodeAdded, pointLightNodeRemoved);
			directionalLightNodes = register(engine, DirectionalLightNode, directionalLightNodeAdded, directionalLightNodeRemoved);
		}
		
		private function register(engine:Engine, nodeClazz:Class, added:Function, removed:Function):NodeList {
			var nodes:NodeList;
			nodes = engine.getNodeList(nodeClazz);
			nodes.nodeAdded.add(added);
			nodes.nodeRemoved.add(removed);
			
			var node:Node;
			for (node = nodes.head; node; node = node.next) {
				added(node);
			}
			return nodes;
		}
		
		private function pointLightNodeAdded(node:PointLightNode):void {
			lightLayer.addLight(node.light);
		}
		
		private function pointLightNodeRemoved(node:PointLightNode):void {
			lightLayer.removeLight(node.light);
		}
		
		private function directionalLightNodeAdded(node:DirectionalLightNode):void {
			lightLayer.addLight(node.light);
		}
		
		private function directionalLightNodeRemoved(node:DirectionalLightNode):void {
			lightLayer.removeLight(node.light);
		}
		
		override public function removeFromEngine(engine:Engine):void {
			super.removeFromEngine(engine);
			var node:PointLightNode;
			for (node = pointLightNodes.head; node; node = node.next) {
				pointLightNodeRemoved(node);
			}
			engine.releaseNodeList(PointLightNode);
			pointLightNodes = null;
		}
		
		override public function update(time:Number):void {
			super.update(time);
			var node:PointLightNode;
			updateLights(pointLightNodes);
			updateLights(directionalLightNodes);
			
		}
		
		private function updateLights(nodes:NodeList):void {
			var node:Node;
			for (node = nodes.head; node; node = node.next) {
				if (node is PointLightNode) {
					var pNode:PointLightNode = node as PointLightNode;
					var location:Point = CoordinateUtil.isometricToScreen(pNode.position.x, pNode.position.y, map.tileWidth, map.tileHeight);
					pNode.light.x = location.x + (map.width * map.tileWidth/2);
					pNode.light.y = location.y;
					pNode.light.radius = pNode.vision.radius;
					pNode.light.brightness = pNode.vision.brightness;
				} else if (node is DirectionalLightNode) {
					var dNode:DirectionalLightNode = node as DirectionalLightNode;
					dNode.light.brightness = dNode.vision.brightness;
				}
			}
		}
		
	}
}